package com.kuaimacode.kframework.api.controller.user;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.kuaimacode.kframework.api.controller.BaseController;
import com.kuaimacode.kframework.api.service.*;
import com.kuaimacode.kframework.api.vo.request.BindBankCardReq;
import com.kuaimacode.kframework.api.vo.request.DrawApplyReq;
import com.kuaimacode.kframework.api.vo.response.BankCardResp;
import com.kuaimacode.kframework.api.vo.response.DrawResp;
import com.kuaimacode.kframework.common.JsonResult;
import com.kuaimacode.kframework.component.SmsRecordService;
import com.kuaimacode.kframework.constants.PageConstants;
import com.kuaimacode.kframework.exception.ErrorEnum;
import com.kuaimacode.kframework.mybatis.models.bankcard.BankCardManagement;
import com.kuaimacode.kframework.mybatis.models.sysparam.SysParam;
import com.kuaimacode.kframework.mybatis.models.user.*;
import com.kuaimacode.kframework.util.BanKCardValidateUtil;
import com.kuaimacode.kframework.util.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

@RestController
@RequestMapping("/account")
@Api(tags = "用户账户",description = "用户账户相关api")
public class UserAccountController extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(UserAccountController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private UserAccountDetailService userAccountDetailService;

    @Autowired
    private UserBankCardAccountService accountService;

    @Autowired
    private SmsRecordService smsRecordService;

    @Autowired
    private UserDrawApplyService drawApplyService;

    @Autowired
    private BankCardManagementService managementService;

    @Autowired
    private SysParamService sysParamService;

    @Autowired
    private UploadService uploadService;

    @Autowired
    private UserCertifacateService certifacateService;

    @Autowired
    private UserAccountDetailService accountDetailService;

    @Autowired
    SysParamService paramService;

    private static final String img = "1bg.jpg";

    private static final String logo = "5logo.jpg";

    @GetMapping(value="/bal")
    @ApiOperation(value = "账户余额查询", notes="账户余额查询,返回账户余额:account_bal,代收款余额：collect_bal,预计收入 :expect_bal")
    public JsonResult getAccountBal(){
        User user = userService.getById(getUserId());
        Map map = new HashMap<>();
        map.put("account_bal",user.getAccountBalance());
        map.put("collect_bal",user.getCollectBal());
        //TODO 预计收入查询。。
        map.put("expect_bal",10);
        return JsonResult.success(map);
    }

    @GetMapping(value="/getWithdrawRate")
    @ApiOperation(value = "查询系统提现手续费", notes="查询系统提现手续费单位（%）")
    public JsonResult getWithdrawRate(){
        SysParam sysParam = sysParamService.findByName("WITHDRAW_RATE");
        return JsonResult.success(sysParam.getValue());
    }

    @ApiOperation(value = "查询账户明细", notes="查询地址列表")
    @GetMapping("/accountDetail")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "accountType", value = "账户类型 1 余额账户 2 代收款账户", required = true, dataType = "string"),
        @ApiImplicitParam(name = "queryMonth", value = "查询月份 格式：2019-01 非必输，不输入查询所有明细，输入查询当前月份及当前月份之前的明细，", required = false, dataType = "")
    })
    public JsonResult<UserAccountDetail> index(@RequestParam(value = "pageNum", required = true, defaultValue = PageConstants.PAGE_NUM+"") int pageNum,
                            @RequestParam(value = "pageSize", required = true, defaultValue = PageConstants.PAGE_SIZE+"") int pageSize, String accountType,String queryMonth) {
        PageInfo pageInfo = userAccountDetailService.queryUserAccountDetailListPage(pageNum, pageSize,accountType,getUserId(),queryMonth);
        List<UserAccountDetail> list = pageInfo.getList();
        if(list!=null && list.size()>0){
            Map<String,List<UserAccountDetail>> map =  new HashMap();
            for(UserAccountDetail detail:list){
                Date tranDate = detail.getCreateDt();

                String tranMon = DateUtil.format(tranDate,DateUtil.MONTG_DATE_FORMAT);
                List<UserAccountDetail> monList = map.get(tranMon);
                if(monList == null) monList = new ArrayList<>();
                monList.add(detail);

                map.put(tranMon,monList);
            }
            map = sortMapByKey(map);


            List l = new ArrayList();
            l.add(map);


            pageInfo.setList(l);
        }

        return JsonResult.success(pageInfo);
    }

    /**
     * 使用 Map按key进行排序
     * @param map
     * @return
     */
    public static Map<String, List<UserAccountDetail>> sortMapByKey(Map<String, List<UserAccountDetail>> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }

        Map<String, List<UserAccountDetail>> sortMap = new TreeMap<String, List<UserAccountDetail>>(
                new MapKeyComparator());

        sortMap.putAll(map);

        return sortMap;
    }


    @ApiOperation(value = "我的-银行卡列表", notes = "银行卡列表")
    @GetMapping(value = "/getBankList")
    public JsonResult<UserBankCardAccount> getBankList(@RequestParam(value = "pageNum", required = true, defaultValue = PageConstants.PAGE_NUM+"") int pageNum,
                                                 @RequestParam(value = "pageSize", required = true, defaultValue = PageConstants.PAGE_SIZE+"") int pageSize) {
        PageInfo<UserBankCardAccount> accounts = accountService.getBankCardList(getUserId(),pageNum,pageSize);
        for (UserBankCardAccount account:accounts.getList()){
            QueryWrapper<UserBankCardAccount> accountQueryWrapper = new QueryWrapper<>();
            BankCardManagement cardManagement = managementService.getById(account.getBankId());
            account.setBankCardImg(uploadService.getPicUrlPath(cardManagement.getBankCardImg()));
            account.setBankCardLogo(uploadService.getPicUrlPath(cardManagement.getBankCardLogo()));
        }
        return JsonResult.success(accounts);
    }

    @ApiOperation(value = "我的-绑定银行卡", notes = "绑定银行卡")
    @PostMapping(value = "/bindBankCard")
    @ApiImplicitParam(name = "bankCardReq", value = "BindBankCardReq实体", required = true, dataType = "BindBankCardReq")
    public JsonResult<BankCardResp> bindBankCard(@RequestBody BindBankCardReq bankCardReq) {
        String message =  BanKCardValidateUtil.checkBankCard(bankCardReq.getBankCardNumber());
        if (StringUtils.isNotEmpty(message)){
            return JsonResult.failure(message);
        }
        if (StringUtils.isEmpty(bankCardReq.getBankCardId())){
            return JsonResult.failure("银行卡id为空");
        }
        if (accountService.saveBankData(bankCardReq,getUserId())){
            List<BankCardResp> cardResps = accountService.getBankListByUserId(getUserId());
            for (BankCardResp resp:cardResps){
//                if (String.utresp.getBankCardId())
                if (resp.getBankCardId()==null||resp.getBankCardId()==0){
                    resp.setBankCardImg(uploadService.getPicUrlPath(img));
                    resp.setBankCardLogo(uploadService.getPicUrlPath(logo));
                }else{
                    BankCardManagement management =  managementService.getById(resp.getId());
                    if (management ==null){
                        resp.setBankCardLogo(uploadService.getPicUrlPath(logo));
                        resp.setBankCardImg(uploadService.getPicUrlPath(img));
                    }else{
                        resp.setBankCardImg(uploadService.getPicUrlPath(management.getBankCardImg()));
                        resp.setBankCardLogo(uploadService.getPicUrlPath(management.getBankCardLogo()));
                    }
                }
            }
            return JsonResult.success(accountService.getBankListByUserId(getUserId()));
        }
        return JsonResult.failure(ErrorEnum.SYSTEM_ERROR.getCode(), ErrorEnum.SYSTEM_ERROR.getMsg());
    }

//    @ApiOperation(value = "我的-绑定银行卡", notes = "绑定银行卡")
//    @PostMapping(value = "/drawCash")
//    @ApiImplicitParam(name = "bankCardReq", value = "BindBankCardReq实体", required = true, dataType = "BindBankCardReq")
//    public JsonResult<BankCardResp> drawCash(@RequestBody BindBankCardReq bankCardReq) {
//        String message =  BanKCardValidateUtil.checkBankCard(bankCardReq.getBankCardNumber());
//        if (StringUtils.isNotEmpty(message)){
//            return JsonResult.failure(message);
//        }
//        if (!smsRecordService.validVerifyCode(bankCardReq.getBankCardPhoneNumber(), bankCardReq.getSmsCode())){
//            return JsonResult.failure(ErrorEnum.VERIFY_CODE_VALID_ERROR.getCode(),
//                    ErrorEnum.VERIFY_CODE_VALID_ERROR.getMsg());
//        }
//        if (accountService.saveBankData(bankCardReq,getUserId())){
//            return JsonResult.success(accountService.getBankListByUserId(getUserId()));
//        }+
//        return JsonResult.failure(ErrorEnum.SYSTEM_ERROR.getCode(), ErrorEnum.SYSTEM_ERROR.getMsg());
//    }

    @ApiOperation(value = "我的-提现历史", notes = "提现历史(提现仅在师傅页面存在)")
    @PostMapping(value = "/drawHistory")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "date", value = "查询月份 格式：2019-01 非必输，不输入查询所有明细，输入查询当前月份及当前月份之前的明细，", required = false, dataType = "")
    })
    public JsonResult<UserDrawApply> drawHistory(@RequestParam(value = "pageNum", required = true, defaultValue = PageConstants.PAGE_NUM+"") int pageNum,
                                             @RequestParam(value = "pageSize", required = true, defaultValue = PageConstants.PAGE_SIZE+"") int pageSize, String date) {
       PageInfo<UserDrawApply> drawApplyPageInfo = drawApplyService.getDrawHistList(pageNum,pageSize,getUserId(),"2",date);
        List<UserDrawApply> list = drawApplyPageInfo.getList();
        Map<String,List<UserDrawApply>> map =  new HashMap();
        for (UserDrawApply drawApply:list) {
            String dataStr = DateUtil.dateToString(drawApply.getCreateDt(),DateUtil.MONTG_DATE_FORMAT);
            List<UserDrawApply> userDrawApplies = map.get(dataStr);
            if (CollectionUtils.isEmpty(userDrawApplies)){
                userDrawApplies = new ArrayList<>();
            }
            userDrawApplies.add(drawApply);
            map.put(dataStr,userDrawApplies);
        }
        if (map == null || map.isEmpty()) {
            return JsonResult.success(drawApplyPageInfo);
        }
        Map<String, List<UserDrawApply>> sortMap = new TreeMap<String, List<UserDrawApply>>(
                new MapKeyComparator());

        sortMap.putAll(map);
        List l = new ArrayList();
        l.add(sortMap);

        drawApplyPageInfo.setList(l);
        return JsonResult.success(drawApplyPageInfo);
    }

    @ApiOperation(value = "我的-可提余额查询", notes = "可提余额查询(提现仅在师傅页面存在)")
    @PostMapping(value = "/drawMessage")
    public JsonResult<DrawResp> drawMessage() {
        User user = userService.getById(getUserId());
        DrawResp resp = new DrawResp();
        resp.setAccountBalance(String.valueOf(user.getAccountBalance()));
        resp.setCopyDesc("");
        return JsonResult.success(resp);
    }

    @ApiOperation(value = "我的-提现申请", notes = "提现申请(提现仅在师傅页面存在)")
    @PostMapping(value = "/drawApply")
    public JsonResult<DrawResp> drawApply(@RequestBody DrawApplyReq drawApplyReq) {
        logger.info("提现申请请求入参:{}", JSON.toJSONString(drawApplyReq));
        if (drawApplyReq.getAccountId()==null){
            return JsonResult.failure("账户Id为空");
        }
        if (StringUtils.isEmpty(drawApplyReq.getApplyAmount())||"0".equals(drawApplyReq.getApplyAmount())){
            return JsonResult.failure("申请金额为空或者为0");
        }
        Long userId = getUserId();
        //申请添加记录后-余额减少
        User user = userService.getById(userId);
        BigDecimal drawAmount = BigDecimal.ZERO;
        SysParam sysParam = paramService.findByName("WITHDRAW_RATE");
        if (StringUtils.equals("1",drawApplyReq.getAccountType())){
            BigDecimal accountBlance = user.getAccountBalance();
            BigDecimal applyAmount = new BigDecimal(drawApplyReq.getApplyAmount());
            if (accountBlance.compareTo(applyAmount)==-1){
                return JsonResult.failure("申请余额超过余额");
            }
            BigDecimal account =  accountBlance.subtract(applyAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
            user.setAccountBalance(account);
            drawAmount = account;
            if (userService.updateById(user)){
                insertAccountDetail(String.valueOf(applyAmount),getUserId(),"用户提现","1",null,"6",account);
            }
        }else if(StringUtils.equals("2",drawApplyReq.getAccountType())){
            BigDecimal collectBal = user.getCollectBal();
            BigDecimal applyAmount = new BigDecimal(drawApplyReq.getApplyAmount());
            if (collectBal.compareTo(applyAmount)==-1){
                return JsonResult.failure("申请余额超过余额");
            }
            BigDecimal amount = collectBal.subtract(applyAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
            drawAmount = amount;
            user.setCollectBal(amount);
            if (userService.updateById(user)){
                insertAccountDetail(String.valueOf(applyAmount),getUserId(),"代收货款提现","2",null,"6",amount);
            }
        }else{
            return JsonResult.failure("账户类型错误");
        }
        drawApplyService.saveDrawApply(drawApplyReq,getUserId(),drawAmount);
        return JsonResult.success();
    }

    @ApiOperation(value = "银行卡下拉列表", notes = "银行卡下拉列表")
    @GetMapping(value = "/bankCardChoice")
    public JsonResult<BankCardManagement> bankCardChoice(String bankCardNumber) {
        //校验卡号是否合法
        if(bankCardNumber==null||(bankCardNumber.trim().length()<16||bankCardNumber.trim().length()>19))
            return JsonResult.failure(ErrorEnum.BANK_CARD_ERR.getCode(), ErrorEnum.BANK_CARD_ERR.getMsg());
        //校验卡号是否存在
        if(accountService.checkIsExists(getUserId(),bankCardNumber))
            return JsonResult.failure(ErrorEnum.BANK_CARD_EXIST.getCode(), ErrorEnum.BANK_CARD_EXIST.getMsg());

        UserCertifacate certifacate = certifacateService.selectByUserId(getUserId());
        List<BankCardManagement> cardManagements = managementService.getBankCardList(bankCardNumber);
        for (BankCardManagement management:cardManagements){
            if (StringUtils.isNotEmpty(management.getBankCardImg())){
                management.setBankCardImg(uploadService.getPicUrlPath(management.getBankCardImg()));
            }else{
                management.setBankCardImg(uploadService.getPicUrlPath(img));
            }
            if (StringUtils.isNotEmpty(management.getBankCardLogo())){
                management.setBankCardLogo(uploadService.getPicUrlPath(management.getBankCardLogo()));
            }else{
                management.setBankCardLogo(uploadService.getPicUrlPath(logo));
            }
        }
        return JsonResult.success(cardManagements);
    }

    @Transactional
    public void  insertAccountDetail(String income,Long userId,String tranDesc,String accountType,String orderNo,String inOutType,BigDecimal accountBalance){
        try {
            Date now = new Date();
            UserAccountDetail accountDetail = new UserAccountDetail();
            accountDetail.setAccountType(accountType);
            accountDetail.setAccoutWay(4L);
            accountDetail.setDetailType("1");
            accountDetail.setAmount(String.valueOf(income));
            accountDetail.setTranDesc(tranDesc);
            accountDetail.setInOutType(inOutType);
            accountDetail.setStatus("0");
            accountDetail.setCreateDt(now);
            accountDetail.setUpdateDt(now);
            accountDetail.setUserId(userId);
            accountDetail.setOutTradeNo(orderNo);
            accountDetail.setTranAmount(accountBalance);
            accountDetailService.save(accountDetail);
        }catch (Exception ex){
            System.out.println("插入账户明细表异常");
        }
    }

}

class MapKeyComparator implements Comparator<String>{

    @Override
    public int compare(String str1, String str2) {

        return str2.compareTo(str1);
    }
}



